# 变量定义
IMAGE_NAME := hub-modules-2-modelhub2
VERSION := latest
NAMESPACE := default
CLUSTER_NAME := modelhub-cluster

# 检测操作系统类型
ifeq ($(OS),Windows_NT)
    SLEEP = timeout $(1) > nul 2>&1 || ping -n $$(expr $(1) + 1) 127.0.0.1 > nul 2>&1
else
    UNAME_S := $(shell uname -s)
    ifeq ($(UNAME_S),Linux)
        SLEEP = sleep $(1)
    endif
    ifeq ($(UNAME_S),Darwin)
        SLEEP = sleep $(1)
    endif
endif

# 1.运行此命令即可启动（并通过网页访问）
# 完全重新部署（包括删除集群后重建集群）
.PHONY: redeploy
redeploy:
	@echo "=== Full Redeployment ==="
	@echo "1. Deleting existing cluster..."
	@make delete-cluster
	@echo "\n2. Creating new cluster..."
	@make create-cluster
	@echo "\n3. Loading image..."
	@make load-image
	@echo "\n4. Deploying service..."
	@make up
	@echo "\n5. Testing network access..."
	@make test-network
	@echo "\nRedeployment complete. Service should be accessible at:"
	@echo "- http://localhost:8000 (via NodePort)"
	@echo "- http://localhost:8001 (via direct container port)"

# 安装必要工具（Windows）
.PHONY: install-tools
install-tools:
	@echo "=== Installing required tools ==="
ifeq ($(OS),Windows_NT)
	@powershell -ExecutionPolicy RemoteSigned -File install-tools.ps1
else
	@echo "This command is for Windows only"
	@exit 1
endif

# windows上检查工具安装状态(Scoop、Git、Kind、Make)
.PHONY: check-tools
check-tools:
	@echo "=== Checking required tools ==="
ifeq ($(OS),Windows_NT)
	@powershell -Command "\
		Write-Host 'Scoop: ' -NoNewline; \
		if (Get-Command scoop -ErrorAction SilentlyContinue) { Write-Host 'Installed' -ForegroundColor Green } else { Write-Host 'Not installed' -ForegroundColor Red }; \
		Write-Host 'Git: ' -NoNewline; \
		if (Get-Command git -ErrorAction SilentlyContinue) { Write-Host 'Installed' -ForegroundColor Green } else { Write-Host 'Not installed' -ForegroundColor Red }; \
		Write-Host 'Kind: ' -NoNewline; \
		if (Get-Command kind -ErrorAction SilentlyContinue) { Write-Host 'Installed' -ForegroundColor Green } else { Write-Host 'Not installed' -ForegroundColor Red }; \
		Write-Host 'Make: ' -NoNewline; \
		if (Get-Command make -ErrorAction SilentlyContinue) { Write-Host 'Installed' -ForegroundColor Green } else { Write-Host 'Not installed' -ForegroundColor Red }"
else
	@echo "This command is for Windows only"
	@exit 1
endif


# 创建新集群
.PHONY: create-cluster
create-cluster:
	@echo "=== Creating new Kind cluster ==="
	@if kind get clusters | grep -q $(CLUSTER_NAME); then \
		echo "Cluster $(CLUSTER_NAME) already exists"; \
		echo "Current context: $$(kubectl config current-context)"; \
		echo "Use 'make clean-cluster' first if you want to recreate the cluster"; \
		exit 1; \
	fi
	@echo "Creating new cluster..."
	@kind create cluster --name $(CLUSTER_NAME) --config kind-config.yaml || (echo "Failed to create cluster" && exit 1)
	@echo "Waiting for cluster to be ready..."
	@$(call SLEEP,5)
	@kubectl wait --for=condition=ready node --all --timeout=60s || true
	@echo "Cluster is ready"
	@echo "Current context: $$(kubectl config current-context)"
	@echo "Cluster information:"
	@kubectl cluster-info

# 检查 K8s 环境
.PHONY: check-env
check-env:
	@echo "=== Checking Kubernetes Environment ==="
	@echo "Current context: $$(kubectl config current-context)"
	@if [ "$$(kubectl config current-context)" != "kind-$(CLUSTER_NAME)" ]; then \
		echo "Error: Wrong context. Expected: kind-$(CLUSTER_NAME)"; \
		echo "Current contexts:"; \
		kubectl config get-contexts; \
		exit 1; \
	fi
	@kubectl cluster-info > /dev/null || (echo "Error: Kubernetes cluster not accessible" && exit 1)
	@echo "Kubernetes cluster is accessible"

# 基本镜像构建命令
.PHONY: build
build:
	@echo "=== Building Docker image ==="
	@docker compose build
	@echo "Image built: $(IMAGE_NAME):$(VERSION)"
	@docker images | grep $(IMAGE_NAME)

# 启动服务
.PHONY: up
up: check-env
	@echo "=== Deploying to Kubernetes ==="
	@echo "Using context: $$(kubectl config current-context)"
	@echo "1. Creating ConfigMap..."
	-kubectl delete configmap modelhub-static -n $(NAMESPACE) --ignore-not-found
	kubectl create configmap modelhub-static --from-file=static/ -n $(NAMESPACE)
	@echo "2. Applying Kubernetes resources..."
	kubectl apply -f k8s/deployment.yaml
	kubectl apply -f k8s/service.yaml
	kubectl apply -f k8s/hpa.yaml
	@echo "3. Checking deployment status..."
	@$(call SLEEP,10)
	@echo "\nPod Status:"
	@kubectl get pods -l app=modelhub -n $(NAMESPACE)
	@echo "\nPod Logs:"
	@kubectl logs -l app=modelhub -n $(NAMESPACE) --tail=20 || true
	@echo "\nPod Events:"
	@kubectl get events -n $(NAMESPACE) --field-selector involvedObject.kind=Pod,involvedObject.name=$$(kubectl get pods -l app=modelhub -n $(NAMESPACE) -o jsonpath="{.items[0].metadata.name}")
	@echo "\nWaiting for pods to be ready..."
	@kubectl wait --for=condition=ready pod -l app=modelhub -n $(NAMESPACE) --timeout=90s || (echo "\nPods failed to start. Check pod status and logs above." && exit 1)
	@echo "\nService is ready"
	@make info

# 停止服务
.PHONY: down
down: check-env
	@echo "Removing Kubernetes resources..."
	kubectl delete -f k8s/hpa.yaml --ignore-not-found
	kubectl delete -f k8s/service.yaml --ignore-not-found
	kubectl delete -f k8s/deployment.yaml --ignore-not-found
	kubectl delete configmap modelhub-static --ignore-not-found -n $(NAMESPACE)
	@echo "Resources removed"

# 重启服务
.PHONY: restart
restart:
	@echo "Restarting service..."
	@make down
	@make up

# 扩缩容
.PHONY: scale
scale:
	@if [ "$(replicas)" = "" ]; then \
		echo "Usage: make scale replicas=<number>"; \
		exit 1; \
	fi
	@echo "Scaling deployment to $(replicas) replicas..."
	kubectl scale deployment modelhub --replicas=$(replicas) -n $(NAMESPACE)

# 查看日志
.PHONY: logs
logs:
	@echo "Showing logs for modelhub pods..."
	kubectl logs -f -l app=modelhub -n $(NAMESPACE)

# 查看状态
.PHONY: ps
ps:
	@echo "=== Pods ==="
	@kubectl get pods -l app=modelhub -n $(NAMESPACE)
	@echo "\n=== Services ==="
	@kubectl get svc modelhub -n $(NAMESPACE)
	@echo "\n=== HPA Status ==="
	@kubectl get hpa modelhub -n $(NAMESPACE)

# 进入容器
.PHONY: exec
exec:
	@POD=$$(kubectl get pod -l app=modelhub -n $(NAMESPACE) -o jsonpath="{.items[0].metadata.name}"); \
	if [ "$$POD" = "" ]; then \
		echo "No running pods found"; \
		exit 1; \
	fi; \
	echo "Executing shell in pod: $$POD"; \
	kubectl exec -it $$POD -n $(NAMESPACE) -- sh

# 显示服务信息
.PHONY: info
info:
	@echo "=== Service Information ==="
	@echo "Service URL: http://localhost:8000"
	@echo "LoadBalancer IP: $$(kubectl get svc modelhub -n $(NAMESPACE) -o jsonpath="{.status.loadBalancer.ingress[0].ip}")"
	@echo "\nEndpoints:"
	@kubectl get endpoints modelhub -n $(NAMESPACE)

# 检查服务健康状态
.PHONY: health
health:
	@echo "=== Health Check ==="
	@echo "Pod Status:"
	@kubectl get pods -l app=modelhub -n $(NAMESPACE) -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,READY:.status.containerStatuses[0].ready
	@echo "\nEvents:"
	@kubectl get events -n $(NAMESPACE) --field-selector involvedObject.kind=Pod,involvedObject.name=$(shell kubectl get pods -l app=modelhub -n $(NAMESPACE) -o jsonpath="{.items[0].metadata.name}")

# 帮助信息
.PHONY: help
help:
	@echo "Available commands:"
	@echo "  make build    - Build Docker image"
	@echo "  make up       - Start services"
	@echo "  make down     - Stop services"
	@echo "  make restart  - Restart services"
	@echo "  make logs     - View logs"
	@echo "  make ps       - List running services"
	@echo "  make exec     - Enter container shell"
	@echo "  make info     - Show service information"
	@echo "  make scale    - Scale deployment"
	@echo "  make health   - Check service health"
	@echo "  make switch-context - Switch to a new Kubernetes context"
	@echo "  make list-contexts - List all available Kubernetes contexts"
	@echo "  make delete-context - Delete a Kubernetes context"
	@echo "Context Management:"
	@echo "  make switch-context  - Switch to modelhub context"
	@echo "  make list-contexts   - List all available contexts"
	@echo "  make delete-context  - Delete modelhub context"

# 检查 K8s 环境
.PHONY: check
check:
	@echo "=== Kubernetes Context ==="
	@kubectl config current-context
	@echo "\n=== Cluster Info ==="
	@kubectl cluster-info
	@echo "\n=== Node Status ==="
	@kubectl get nodes
	@echo "\n=== System Pods ==="
	@kubectl get pods -n kube-system

# 清理所有资源（慎用，会删除所有容器）
.PHONY: clean-all
clean-all:
	@echo "=== Cleaning all resources ==="
	@echo "Stopping all Kubernetes related containers..."
	@docker ps -q --filter "name=k8s_" | xargs -r docker stop
	@docker ps -q --filter "name=kind-" | xargs -r docker stop
	@echo "Removing all Kubernetes related containers..."
	@docker ps -qa --filter "name=k8s_" | xargs -r docker rm
	@docker ps -qa --filter "name=kind-" | xargs -r docker rm
	@echo "Deleting kind cluster..."
	@kind delete cluster --name $(CLUSTER_NAME) || true
	@echo "Removing kind network..."
	@docker network rm kind || true
	@echo "Cleaning Docker system..."
	@docker system prune -f
	@echo "All resources cleaned"

# 检查端口
.PHONY: check-ports
check-ports:
	@echo "=== Checking required ports ==="
	@echo "Checking port 8001..."
	@if [ "$$(docker ps -q -f publish=8001)" ]; then \
		echo "Port 8001 is in use by container:"; \
		docker ps -f publish=8001; \
		exit 1; \
	else \
		echo "Port 8001 is available"; \
	fi

# 删除集群（删除集群名$(CLUSTER_NAM）
.PHONY: delete-cluster
delete-cluster:
	@echo "=== Deleting Kind cluster ==="
	@if [ "$$(kubectl config current-context)" = "kind-$(CLUSTER_NAME)" ]; then \
		kubectl config use-context docker-desktop || true; \
	fi
	@if kind get clusters | grep -q $(CLUSTER_NAME); then \
		kind delete cluster --name $(CLUSTER_NAME); \
		echo "Cluster $(CLUSTER_NAME) deleted"; \
	else \
		echo "Cluster $(CLUSTER_NAME) does not exist"; \
	fi

# 更新 deployment.yaml 中的端口
.PHONY: update-port
update-port:
	@echo "=== Updating service port in deployment files ==="
	@sed -i 's/port: 8000/port: 8001/g' k8s/service.yaml
	@echo "Updated service port to 8001"

# 检查集群状态
.PHONY: cluster-status
cluster-status:
	@echo "=== Cluster Status ==="
	@echo "Current context: $$(kubectl config current-context)"
	@echo "\nClusters:"
	@kind get clusters
	@echo "\nNodes:"
	@kubectl get nodes
	@echo "\nPods:"
	@kubectl get pods -A

# 调试部署问题
.PHONY: debug-deployment
debug-deployment:
	@echo "=== Debugging Deployment Issues ==="
	@echo "\n1. Checking Node Status:"
	@kubectl get nodes
	@echo "\n2. Checking Pod Status:"
	@kubectl get pods -l app=modelhub -n $(NAMESPACE) -o wide
	@echo "\n3. Checking Pod Details:"
	@kubectl describe pods -l app=modelhub -n $(NAMESPACE)
	@echo "\n4. Checking Pod Logs:"
	@kubectl logs -l app=modelhub -n $(NAMESPACE) --tail=50 || true
	@echo "\n5. Checking Events:"
	@kubectl get events -n $(NAMESPACE) --sort-by='.lastTimestamp'
	@echo "\n6. Checking Service Status:"
	@kubectl describe service modelhub -n $(NAMESPACE)
	@echo "\n7. Checking Images in Kind:"
	@docker exec -it modelhub-cluster-control-plane crictl images | grep modelhub

# 加载镜像到 Kind(先build镜像)
# Images in cluster:docker.io/library/hub-modules-2-modelhub2       latest               40402d6cb5381       8.89MB
.PHONY: load-image
load-image: build
	@echo "=== Loading image to Kind cluster ==="
	@echo "Current context: $$(kubectl config current-context)"
	@if ! docker images | grep -q "$(IMAGE_NAME)"; then \
		echo "Error: Image $(IMAGE_NAME):$(VERSION) not found locally"; \
		exit 1; \
	fi
	@echo "Loading image to cluster..."
	@kind load docker-image $(IMAGE_NAME):$(VERSION) --name $(CLUSTER_NAME)
	@echo "Image loaded successfully"
	@echo "Images in cluster:"
	@docker exec -it modelhub-cluster-control-plane crictl images | grep modelhub

# 检查静态文件夹
.PHONY: check-static
check-static:
	@echo "=== Checking static files ==="
	@echo "Current directory: $$(pwd)"
	@echo "Directory listing:"
ifeq ($(OS),Windows_NT)
	@powershell -Command "Get-ChildItem -Directory | Select-Object Name"
	@powershell -Command "if (Test-Path 'static') { Write-Output \"\nStatic directory exists\"; Get-ChildItem static } else { Write-Output \"Error: static directory not found\"; exit 1 }"
else
	@ls -la | grep "^d"
	@if [ -d "static" ]; then echo "\nStatic directory exists" && ls -l static/; else echo "Error: static directory not found" && exit 1; fi
endif
	@echo "\nConfigMap status:"
	-@kubectl get configmap modelhub-static -n $(NAMESPACE) --ignore-not-found || echo "No ConfigMap found"
	@echo "\nConfigMap contents:"
	-@if kubectl get configmap modelhub-static -n $(NAMESPACE) --ignore-not-found > /dev/null 2>&1; then \
		kubectl describe configmap modelhub-static -n $(NAMESPACE); \
	else \
		echo "ConfigMap not found (this is normal if you haven't deployed the application yet)"; \
	fi

# 检查服务访问地址
.PHONY: check-access
check-access:
	@echo "=== Checking Service Access ==="
	@echo "Service Details:"
	@kubectl get svc modelhub -o wide
	@echo "\nPod IPs:"
	@kubectl get pods -l app=modelhub -o wide
	@echo "\nNode IPs:"
	@kubectl get nodes -o wide
	@echo "\nPort Mappings:"
	@docker ps --format "{{.Names}}\t{{.Ports}}" | grep modelhub-cluster
	@echo "\nEndpoints:"
	@kubectl get endpoints modelhub
	@echo "\nTry accessing the service at:"
	@echo "- http://localhost:8000"
	@echo "- http://127.0.0.1:8000"
	@echo "- http://$(shell docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' modelhub-cluster-control-plane):8000"

# 端口转发
.PHONY: port-forward
port-forward:
	@echo "=== Setting up port forward ==="
	@echo "Press Ctrl+C to stop"
	@kubectl port-forward svc/modelhub 8000:8000 --address 0.0.0.0

# 检查服务状态
.PHONY: service-test
service-test:
	@echo "=== Testing Service ==="
	@echo "1. Testing service endpoints..."
	@for ip in localhost 127.0.0.1 $(shell docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' modelhub-cluster-control-plane); do \
		echo "\nTesting http://$$ip:8000"; \
		curl -v http://$$ip:8000 || true; \
		echo "\nTesting http://$$ip:8000/static/"; \
		curl -v http://$$ip:8000/static/ || true; \
	done
	@echo "\n2. Pod Logs:"
	@kubectl logs -l app=modelhub --tail=20

# 网络测试
.PHONY: test-network
test-network:
	@echo "=== Testing Network Access ==="
	@echo "1. Testing NodePort access (8000)..."
	@curl -v http://localhost:8000/static/ || true
	@echo "\n2. Testing direct container access (8001)..."
	@curl -v http://localhost:8001/static/ || true
	@echo "\n3. Testing node IP access..."
	@NODE_IP=$$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' modelhub-cluster-control-plane); \
	echo "Node IP: $$NODE_IP"; \
	curl -v http://$$NODE_IP:30000/static/ || true
	@echo "\n4. Pod Logs:"
	@kubectl logs -l app=modelhub --tail=10



